home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SECDR13A.ZIP / SETENV.ASM < prev    next >
Assembly Source File  |  1993-12-29  |  8KB  |  380 lines

  1.     TITLE    setenv - 12.29.93  Large Model
  2.     .MODEL large
  3. setenv_TEXT   SEGMENT WORD PUBLIC 'CODE'
  4.     ASSUME    CS:setenv_TEXT,DS:setenv_TEXT
  5. ;
  6. ;setenv(char * varname,char * strint)
  7. ;
  8. command db    356 dup (?)
  9. set    db    "set "
  10. CR    equ    0dh
  11. EnvPtr    EQU    2CH    ; Offset in PSP
  12. ComInt    EQU    2EH    ; entry point into first Command.Com
  13.             ; through interpreter
  14.  
  15. SegPtr    EQU    ComInt*4 + 2
  16. sssav    dw    0
  17. spsav    dw    0
  18.  
  19. s_path        dw    05h        ; Size of Path.
  20. d_path        db    "PATH="
  21. s_comspec    dw    08h        ; Size of Comspec=.
  22. d_comspec    db    "COMSPEC="
  23. s_prompt    dw    07h        ; Size of Prompt=.
  24. d_prompt    db    "PROMPT="
  25. s_setenv    dw    07h        ; Size of Setenv=.
  26. d_setenv    db    "SETENV="
  27. s_config    dw    07h        ; Size of Config=.
  28. d_config    db    "CONFIG="
  29. equals        equ    $-1
  30.  
  31. szdat    dw    0    ;Size of environment data.
  32. szvar    dw    0    ;Environment variable size.
  33.  
  34. zero    dw    0    ;constant
  35.  
  36. exit_code    db    00h        ; Normal return
  37.  
  38. envseg dw      0       ;Environment segment address.
  39. envsz    dw    0    ;Environment size in bytes.
  40.  
  41. get4d_err    db    "Error - can't find/recognize environment space.$"
  42.  
  43. msg00        db    "$"
  44. msg01        db    "$"
  45. msg02        db    "environment variable erased$"
  46. msg03        db    "environment variable created$"
  47. msg04        db    "$"
  48. msg05        db    "$"
  49. msg06        db    "$"
  50. msg07        db    "$"
  51. msg08        db    "$"
  52. msg09        db    "$"
  53. msg10        db    "environment space full$"
  54. msgtab        dw    msg00
  55.         dw    msg01
  56.         dw    msg02
  57.         dw    msg03
  58.         dw    msg04
  59.         dw    msg05
  60.         dw    msg06
  61.         dw    msg07
  62.         dw    msg08
  63.         dw    msg09
  64.         dw    msg10
  65.  
  66.     public    _setenv
  67. _setenv proc far
  68.     push    bp
  69.     mov    bp,sp
  70.     push    si
  71.     push    di
  72.     push    es
  73.     push    ds
  74.  
  75.     push    cs
  76.     pop    ds
  77.  
  78.     les    di,ss:[bp+6]    ;char * varname
  79.     mov    bx,di
  80.     mov    cx,255
  81.     mov    al,0
  82.     cld
  83.     repne scasb
  84.     sub    di,bx
  85.     dec    di
  86.     mov    szvar,di    ;size of env var
  87.     les    di,ss:[bp+10]     ;char * string
  88.     mov    bx,di
  89.     mov    cx,255
  90.     mov    al,0
  91.     cld
  92.     repne scasb
  93.     sub    di,bx
  94.     dec    di
  95.     mov    szdat,di    ;size of data var
  96.  
  97.     xor   si,si        ;Point to segment 0
  98.     mov   es,si
  99.     mov   si, word ptr es:[SegPtr]
  100.     mov   ax,si
  101.     dec   ax
  102.     mov   es,ax
  103.  
  104.  
  105. get4d:
  106. ;    find memory descriptor + PSP
  107.     cmp byte ptr es:0,4dh
  108.     jnz inc_seg
  109.     cmp word ptr es:10h,20cdh
  110.     jz  got4d
  111.  
  112. inc_seg:
  113.     mov ax, es        ; Increment
  114.     inc ax            ;   to the next
  115.     mov es, ax        ;      segment boundary.
  116.  
  117. ;    limit search
  118.     mov bx,cs
  119.     cmp ax, bx        ; Have we gone passed current PSP?
  120.     jbe get4d        ; No. Continue.
  121.     push cs
  122.     pop  ds
  123.     cmp  envseg,0
  124.     jnz  nor_ts
  125.     mov  si,offset get4d_err
  126.     jmp  exitmsg
  127. nor_ts:
  128.     jmp  nor_term         ; Exit.
  129.  
  130.  
  131. got4d:
  132.     mov ax,es:EnvPtr+10h    ; Offset in PSP - Environment
  133.     or ax,ax
  134.     jz inc_seg
  135.     push es
  136.     dec ax
  137.     mov es,ax
  138.     cmp byte ptr es:0,4dh
  139.     jnz nxt_env
  140.     mov ah, 00h
  141.     mov al, es:3        ;Get the number of segments.
  142.     mov bx, 10h
  143.     mul bx            ;Get the number of bytes.
  144.     mov cs:envsz, ax    ;Save it.
  145.  
  146.     mov ax, es        ;Increment
  147.     inc ax            ;  to the environment
  148.     mov es, ax        ;     segment boundary.
  149.  
  150. ;    Just a double check for environment space.
  151.  
  152.     xor di,di
  153.     mov si, offset d_path    ; Check
  154.     mov cx, s_path        ;   for
  155.     rep cmpsb        ;     PATH=.
  156.     jz got_env
  157.  
  158.     xor di,di
  159.     mov si, offset d_prompt ; Check
  160.     mov cx, s_prompt    ;   for
  161.     rep cmpsb        ;     PROMPT=.
  162.     jz got_env
  163.  
  164.     xor di,di
  165.     mov si, offset d_comspec ;Check
  166.     mov cx, s_comspec    ;    for
  167.     rep cmpsb        ;      COMSPEC=.
  168.     jz got_env
  169.  
  170.     xor di,di
  171.     mov si, offset d_setenv ; Check
  172.     mov cx, s_setenv    ;   for
  173.     rep cmpsb        ;     SETENV=.
  174.     jz got_env
  175.  
  176.     xor di,di
  177.     mov si, offset d_config ; Check
  178.     mov cx, s_config    ;   for
  179.     rep cmpsb        ;     CONFIG=.
  180.     jz got_env
  181.  
  182.     pop es
  183.     jmp inc_seg        ;    to scan some more.
  184.  
  185. got_env:
  186.     mov ax,es        ;don't change same env twice
  187.     cmp cs:envseg,ax       ; may be pointed to by >1 PSP
  188.     je  nxt_env
  189.     mov cs:envseg,es
  190.     call set_env
  191. nxt_env:
  192.     pop es
  193.     jmp inc_seg
  194.  
  195. nor_term:
  196.     push cs
  197.     pop  ds
  198.     mov al, exit_code
  199.     mov ah,0
  200.     add ax,ax        ; index to msg table
  201.     mov si, offset msgtab
  202.     add si,ax
  203.     mov dx,0[si]
  204. exitmsg:
  205.     mov ah, 09h        ; display exit msg
  206.     int 21h
  207.     mov al, exit_code    ; Set termination code.
  208.     cbw
  209. comrtn:
  210.     pop    ds
  211.     pop    es
  212.     pop    di
  213.     pop    si
  214.     pop    bp
  215.     ret
  216. _setenv endp
  217.  
  218. set_env proc  near
  219.     mov ax, es        ; environment to
  220.     mov ds, ax        ;   data segment
  221.     xor si,si        ; environment offset
  222.  
  223.     les    di,ss:[bp+6]    ;char * varname
  224.     mov bl, es:[di]     ;1st char of environment variable.
  225.     jmp short zero1
  226.  
  227.  
  228. ;    Scan through environment for the end,
  229. ;    two null bytes.
  230. lp1:
  231.     lodsb            ; Get a byte.
  232.     cmp al, 00h        ; Is it null?
  233.     jz zero1        ; Yes. Got first null.
  234.     jmp lp1         ; Keep looking.
  235.  
  236. ;    Is the variable there?
  237. zero1:
  238.     lodsb            ; Get a byte.
  239.     cmp al, 00h        ; Is it zero?
  240.     jz write_near        ; Yes.    Jump out.
  241.     cmp al, bl        ; Maybe the env. variable?
  242.     jnz lp1         ; No.  Jump out.
  243.  
  244.     dec si            ; We are N+1.
  245.     mov ax, ds        ; Get the data segment
  246.     mov es, ax        ; and put it in extra segment.
  247.     mov di, si        ; This is our destination.
  248.     mov dx, si        ; Save the address of env. var.
  249.  
  250.     lds    si,ss:[bp+6]    ;char * varname
  251.     mov    cx, cs:szvar    ;Length of variable.
  252.     cld
  253.     rep cmpsb        ; Does it exist?
  254.     jz update
  255.  
  256.     mov ax, es        ; Get the extra segment.
  257.     mov ds, ax        ; and put it in data segment.
  258.     mov si, di        ; Setup the source.
  259.     jmp lp1
  260.  
  261. write_near:
  262.     jmp write
  263.  
  264. ;    The environment variable is there.
  265. ;    Now update the environment variable.
  266. update:
  267.  
  268. update0:
  269.     mov ax, es        ; Get the extra segment.
  270.     mov ds, ax        ; and put it in data segment.
  271.     mov di, dx        ; This is our destination.
  272.     mov si, di        ; Setup the source.
  273.  
  274. update1:
  275.     lodsb            ; Skip
  276.     cmp al, 00h        ;   over
  277.     jnz update1        ;     the variable.
  278.  
  279.     lodsb            ; Look ahead to see
  280.     dec si            ;   if the next byte
  281.     cmp al, 00h        ;     is zero if not
  282.     jz update3        ;    compress the data.
  283.  
  284. update2:
  285.     lodsb            ; Compress
  286.     stosb            ;   the data
  287.     cmp al, 00h        ;     for a
  288.     jnz update2        ;    variable.
  289.  
  290.     lodsb            ; Get a byte.
  291.     dec si
  292.     cmp al, 00h        ; Is it zero?
  293.     jnz update2        ; No.  Get next.
  294.  
  295. update3:
  296. update4:
  297.     mov cx, cs:szdat    ; Length of data.
  298.     cmp cx, 00h        ; null data?
  299.     jnz write1        ; No. Jump out.
  300.  
  301.     mov cx, si        ; End of old environment.
  302.     mov dx, di        ; Current position.
  303.     sub cx, dx
  304.     mov al, 00h        ; Zero
  305.     rep stosb        ;  the rest.
  306.     ret
  307.  
  308. ;    The environment variable isn't there.
  309. ;    Now move the data into place.
  310. write:
  311.     mov ax, ds        ; Get the data segment
  312.     mov es, ax        ; and put it in extra segment.
  313.     dec si            ; We are N+1.
  314.     mov di, si        ; This is our destination.
  315.     mov dx, si        ; save for reset
  316.  
  317. write1:
  318.     mov cx, cs:szdat    ; Environment data length
  319.     jcxz write1a        ; delete if none
  320.     jmp short write2    ; No. Jump out.
  321. write1a:
  322.     mov cs:[exit_code], 08h ; Environment variable not found.
  323.     ret
  324.  
  325. write2:
  326.     lds    si,ss:[bp+6]    ;char * varname
  327.     mov    cx, cs:szvar    ;Set the length.
  328.     call    cpytenv     ;copy to env
  329.     push    cs
  330.     pop    ds
  331.     mov    si, offset equals
  332.     mov    cx,1
  333.     call    cpytenv
  334.     lds    si,ss:[bp+10]    ;char * data
  335.     mov    cx, cs:szdat    ;Set the length.
  336.     call    cpytenv
  337.     push    cs
  338.     pop    ds
  339.     mov    si,offset zero
  340.     mov    cx,2
  341.     call    cpytenv
  342.     ret
  343.  
  344. cpytenv label near
  345. write3:
  346.     mov ah, es:[di]     ; Get destination byte.
  347. write4:
  348.     cmp ah, 00h        ; Is it a zero?
  349.     jnz not_zero        ; No.  Jump out.
  350.     lodsb            ; Get byte.
  351.     stosb            ; Save byte.
  352.     loop write3        ; Loop.
  353.     ret
  354.  
  355.  
  356. not_zero:
  357.     mov ax, di        ; Get the current offset.
  358.     mov bx, cs:envsz    ; Get environment size.
  359.     cmp ax, bx        ; Greater than environment size.
  360.     jge reset        ; Yes.    Jump.
  361.     mov ah, 00h        ; Make it zero.
  362.     jmp write4
  363.  
  364. reset:
  365.     mov di, dx
  366.     mov al, 00h        ; Put zero back.
  367.     stosb
  368.     stosb
  369.     mov exit_code, 0Ah    ; Set code for out of env.,
  370.     pop  ax         ; discard inner return
  371.     ret
  372.  
  373.  
  374.  
  375.     public lastloc
  376. lastloc     label    byte        ; End of program.
  377. set_env endp
  378. setenv_TEXT   ENDS
  379.     END
  380.